package com.fc.advbox.controller.api;

import com.alibaba.fastjson.JSONObject;
import com.fc.advbox.common.ResponseJson;
import com.fc.advbox.controller.admin.BaseController;
import com.fc.advbox.entity.UserTokenAcctEntity;
import com.fc.advbox.entity.UserTokenAcctTxnEntity;
import com.fc.advbox.entity.UserTokenAcctUnlockTxnEntity;
import com.fc.advbox.entity.UserTokenExtractRecordEntity;
import com.fc.advbox.service.IUserTokenAcctService;
import com.fc.advbox.service.IUserTokenAcctTxnService;
import com.fc.advbox.service.IUserTokenExtractRecordService;
import com.fc.advbox.utils.Constant;
import com.fc.advbox.utils.RRException;
import com.fc.advbox.utils.validator.ValidatorUtils;
import com.fc.advbox.utils.validator.group.AddGroup;
import com.fc.advbox.utils.validator.group.UpdateGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by E7450 on 2018/7/29.
 */
@RestController
@RequestMapping("/api/user/token/account")
@Api(value="用户虚拟币账户接口", tags={"用户虚拟币账户接口"})
public class UserTokenAcctController extends BaseController {

    @Autowired
    private IUserTokenAcctService userTokenAcctService;

    @Autowired
    private IUserTokenExtractRecordService userTokenExtractRecordService;

    @Autowired
    private IUserTokenAcctTxnService userTokenAcctTxnService;

    @ApiOperation(value = "POST -- 查询当前用户的虚拟币账号列表",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>可选参数: userId: 用户ID, 可以为null，如果为null则查询当前登陆用户</i></li>" +
                    "<li><i>可选参数: accountType: 账号类型 : key / eos / pai</i></li>" +
                    "<li><i>默认参数: page: 1, 当前页，默认值1 </i></li>" +
                    "<li><i>默认参数: limit: 每次查询个数，默认为20</i></li>" +
                    "</ul>")
    @PostMapping("/list")
    public ResponseJson doQueryList(@RequestBody Map<String, Object> params) {
        //校对并赋值 offset和limit
        calculatePagination(params);
        if(!params.containsKey("userId") || params.get("userId") == null)
        {
            params.put("userId", getUserId());
        }

        List<UserTokenAcctEntity> acctEntityList = userTokenAcctService.queryList(params);
        return ResponseJson.success(acctEntityList);
    }

    /**
     * 保存用户虚拟币账户
     */
    @PostMapping("/save")
    @ApiOperation(value = "添加用户虚拟币账号", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>userId: 用户ID，可选，如果为null，则为自己创建 </i></li>" +
                    "<li><i>accountType: 账号类型 key / eos / pai， 必需 </i></li>" +
                    "<li><i>accountName: 账号名称或备注: 可选 </i></li>" +
                    "<li><i>totalAmount: 账户总共数量 : 可选</i></li>" +
                    "<li><i>ableAmount:  可用数量 : 可选</i></li>" +
                    "<li><i>deblockingAmount: 解锁中数量 : 可选</i></li>" +
                    "<li><i>lockAmount： 已锁定数量 : 可选</i></li>" +
                    "<li><i>status: 状态, 必需, 0: INACTIVE 1: ACTIVE : 可选</i></li>" +
                    "</ul>")
    public ResponseJson save(@RequestBody UserTokenAcctEntity entity){
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());

        if(!Constant.TokenAccountType.verify(entity.getAccountType()))
        {
            throw new RRException("accountType的值不正确!");
        }

        if(entity.getStatus() == null)
        {
            entity.setStatus(Constant.Status.ENABLE.getValue());
        }
        if(entity.getUserId() == null)
        {
            entity.setUserId(getUserId());
        }

        ValidatorUtils.validateEntity(entity, AddGroup.class);

        userTokenAcctService.save(entity);

        return ResponseJson.success();
    }

    /**
     * 更新用户虚拟币账户
     */
    @PutMapping("/update")
    @ApiOperation(value = "更新用户虚拟币账号", response = ResponseJson.class, httpMethod="PUT",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>id: 虚拟币账号ID， 必需 </i></li>" +
                    "<li><i>accountType: 账号类型 key / eos / pai， 必需 </i></li>" +
                    "<li><i>accountName: 账号名称或备注: 可选 </i></li>" +
                    "<li><i>totalAmount: 账户总共数量 : 可选</i></li>" +
                    "<li><i>ableAmount:  可用数量 : 可选</i></li>" +
                    "<li><i>deblockingAmount: 解锁中数量 : 可选</i></li>" +
                    "<li><i>lockAmount： 已锁定数量 : 可选</i></li>" +
                    "<li><i>status: 状态, 必需, 0: INACTIVE 1: ACTIVE : 可选</i></li>" +
                    "</ul>")
    public ResponseJson update(@RequestBody UserTokenAcctEntity entity){
        entity.setUpdateTime(new Date());
        if(entity.getStatus() == null)
        {
            throw new RRException("status不能为空!");
        }
        if(entity.getUserId() == null)
        {
            throw new RRException("userId不能为空!");
        }
        ValidatorUtils.validateEntity(entity, UpdateGroup.class);

        userTokenAcctService.update(entity);

        return ResponseJson.success();
    }

    @ApiOperation(value = "POST -- 批量删除用户虚拟币账号",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>ids: 虚拟币账号ID， 必需 </i></li>" +
                    "</ul>")
    @PostMapping("/delete")
    public ResponseJson doDelete(@RequestBody Long[] ids) {
        if(ids != null){
            for (Long id: ids) {
                userTokenAcctService.delete(id);
            }
        }
        return ResponseJson.success();
    }

    /**
     * 账号数量转换
     */
    @PostMapping("/changeTo")
    @ApiOperation(value = "账号不同状态下的数量转换", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>acctId: 拟币账号ID，必填</i></li>" +
                    "<li><i>changeType: 转换类型 toAble( 解锁中 ---> 可用 ) / toDeblocking(锁定 ---> 解锁中) / toLock(可用 ---> 锁定) 必填 </i></li>" +
                    "<li><i>changeAmount: 转换的数量， 必填 </i></li>" +
                    "</ul>")
    public ResponseJson changeTo(@RequestBody JSONObject params){
        if(!params.containsKey("acctId") || params.get("acctId") == null)
        {
            throw new RRException("acctId不能为空!");
        }
        if(!params.containsKey("changeType") || params.get("changeType") == null)
        {
            throw new RRException("changeType不能为空!");
        }
        if(!Constant.TokenChangeType.verify(params.getString("changeType")))
        {
            throw new RRException("changeType的值不正确!");
        }
        if(!params.containsKey("changeAmount") || params.get("changeAmount") == null)
        {
            throw new RRException("changeAmount不能为空!");
        }
        if(BigDecimal.ONE.compareTo(params.getBigDecimal("changeAmount")) > 0)
        {
            throw new RRException("changeAmount最小值不能低于1!");
        }

        UserTokenAcctEntity entity = userTokenAcctService.changeTo(params);
        return ResponseJson.success(entity);
    }


    /**
     * 虚拟币账户交易记录
     */
    @PostMapping("/txn/list")
    @ApiOperation(value = "获取虚拟币账户交易记录列表", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>acctId: 拟币账号ID，选填</i></li>" +
                    "<li><i>txnType: 账号类型 key / eos / pai， 选填 </i></li>" +
                    "<li><i>changeType: 数量转换类型 toDeblocking - （锁定 --> 解锁中） /  toAble - 解锁中 ---> 可用 / toLock - 可用 ---> 锁定 / deblockingToLock - 解锁中 ---> 锁定， 选填 </i></li>" +
                    "<li><i>默认参数: page: 1, 当前页，默认值1</i></li>" +
                    "<li><i>默认参数: limit: 每次查询个数，默认为20</i></li>" +
                    "</ul>")
    public ResponseJson txnList(@RequestBody JSONObject params){
        //校对并赋值 offset和limit
        calculatePagination(params);

        List<UserTokenAcctTxnEntity> entityList = userTokenAcctTxnService.queryList(params);
        return ResponseJson.success(entityList);
    }


    /**
     * 虚拟币账户解锁中记录
     */
    @PostMapping("/unlock/txn/list")
    @ApiOperation(value = "获取虚拟币账户解锁中记录列表", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>acctId: 拟币账号ID，选填</i></li>" +
                    "<li><i>默认参数: page: 1, 当前页，默认值1</i></li>" +
                    "<li><i>默认参数: limit: 每次查询个数，默认为20</i></li>" +
                    "</ul>")
    public ResponseJson unlockTxnList(@RequestBody JSONObject params){
        //校对并赋值 offset和limit
        calculatePagination(params);

        List<UserTokenAcctUnlockTxnEntity> entityList = userTokenAcctService.queryUnlockTxnList(params);
        return ResponseJson.success(entityList);
    }

    /**
     * 取消解锁中交易
     */
    @PostMapping("/unlock/txn/cancel")
    @ApiOperation(value = "取消解锁中交易", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>unlockingTxnId: 虚拟币解锁交易ID， 必填</i></li>" +
                    "</ul>")
    public ResponseJson cancelUnlockTxn(@RequestBody JSONObject params)
    {
        Long unlockTxnId = params.getLong("unlockingTxnId");
        if(unlockTxnId == null || unlockTxnId == 0)
        {
            throw new RRException("解锁中记录ID不能为空!");
        }
        userTokenAcctService.cancelUnlockingTxn(unlockTxnId);
        return ResponseJson.success();
    }

    /**
     * 用户虚拟币账户提现
     */
    @PostMapping("/extract")
    @ApiOperation(value = "用户虚拟币账号提现", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>tokenAccountId: 拟币账号ID，必填</i></li>" +
                    "<li><i>tokenType: 账号类型 key / eos / pai， 必需 </i></li>" +
                    "<li><i>tokenAddressId: 提现地址ID: 必填 </i></li>" +
                    "<li><i>amount: 体现数量，必须大于手续费+1 : 比填</i></li>" +
                    "<li><i>serviceCharge:  该参数目前在后端定义常量，无需传入</i></li>" +
                    "<li><i>actualAmount: 无需传入，actualAmount = amount - serviceCharge</i></li>" +
                    "</ul>")
    public ResponseJson extract(@RequestBody UserTokenExtractRecordEntity entity){

        ValidatorUtils.validateEntity(entity, AddGroup.class);

        if(!Constant.TokenAccountType.verify(entity.getTokenType()))
        {
            throw new RRException("accountType的值不正确!");
        }
        if(entity.getTokenAccountId() == null)
        {
            throw new RRException("tokenAccountId的值不能为空!");
        }
        if(entity.getTokenAddressId() == null)
        {
            throw new RRException("tokenAddressId的值不能为空!");
        }
        if(entity.getAmount() == null)
        {
            throw new RRException("提现数量不能为空!");
        }
        if(entity.getAmount().compareTo(Constant.DEFAULT_TOKEN_EXTRACT_SERVICE_CHARGE_NUMBER.add(BigDecimal.ONE))< 0)
        {
            throw new RRException("提现数量最少为"+ Constant.DEFAULT_TOKEN_EXTRACT_SERVICE_CHARGE_NUMBER.add(BigDecimal.ONE));
        }

        UserTokenAcctEntity acctEntity = userTokenAcctService.extract(entity);
        return ResponseJson.success(acctEntity);
    }

    /**
     * 虚拟币账户提现记录
     */
    @PostMapping("/extract/txn/list")
    @ApiOperation(value = "获取虚拟币提现记录列表", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>tokenAccountId: 拟币账号ID，选填</i></li>" +
                    "<li><i>tokenType: 账号类型 key / eos / pai， 选填 </i></li>" +
                    "<li><i>tokenAddressId: 提现地址ID: 选填 </i></li>" +
                    "<li><i>默认参数: page: 1, 当前页，默认值1</i></li>" +
                    "<li><i>默认参数: limit: 每次查询个数，默认为20</i></li>" +
                    "</ul>")
    public ResponseJson extractTxnList(@RequestBody JSONObject params){
        //校对并赋值 offset和limit
        calculatePagination(params);

        List<UserTokenExtractRecordEntity> entityList = userTokenExtractRecordService.queryList(params);
        return ResponseJson.success(entityList);
    }
}
